<template>
  <div class="email-verification">
    <!-- 发送验证码 -->
    <div class="verification-input">
      <el-input
        v-model="verificationCode"
        placeholder="请输入6位验证码"
        clearable
        :prefix-icon="Key"
        maxlength="6"
        @input="onCodeInput"
      />
      <el-button
        type="primary"
        :disabled="!canSendCode || sendCodeLoading"
        :loading="sendCodeLoading"
        class="send-code-btn"
        @click="sendVerificationCode"
      >
        {{ sendCodeText }}
      </el-button>
    </div>

    <!-- 验证状态提示 -->
    <div v-if="verificationStatus" class="verification-status">
      <div v-if="verificationStatus === 'success'" class="status-success">
        <el-icon><CircleCheck /></el-icon>
        <span>验证码验证成功</span>
      </div>
      <div v-else-if="verificationStatus === 'error'" class="status-error">
        <el-icon><CircleClose /></el-icon>
        <span>{{ verificationError }}</span>
      </div>
      <div
        v-else-if="verificationStatus === 'verifying'"
        class="status-verifying"
      >
        <el-icon class="loading"><Loading /></el-icon>
        <span>正在验证...</span>
      </div>
    </div>

    <!-- 帮助信息 -->
    <div class="help-info">
      <p class="help-text">
        <el-icon><InfoFilled /></el-icon>
        验证码已发送到您的邮箱，请查收（包括垃圾邮件文件夹）
      </p>
      <p class="help-text">
        <el-icon><Clock /></el-icon>
        验证码有效期为10分钟
      </p>
      <p v-if="remainingSendCount > 0" class="help-text">
        <el-icon><Message /></el-icon>
        今日还可发送 {{ remainingSendCount }} 次验证码
      </p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onUnmounted } from "vue";
import { ElMessage } from "element-plus";
import {
  Key,
  CircleCheck,
  CircleClose,
  Loading,
  InfoFilled,
  Clock,
  Message
} from "@element-plus/icons-vue";
import {
  sendVerificationCodeApi,
  verifyEmailCodeApi,
  UserAuthUtils,
  VerificationType,
  type SendVerificationCodeRequest,
  type VerifyEmailCodeRequest
} from "@/api/user-auth";

// 组件属性
interface Props {
  /** 邮箱地址 */
  email: string;
  /** 验证类型 */
  verificationType: VerificationType;
  /** 是否自动验证 */
  autoVerify?: boolean;
  /** 是否禁用 */
  disabled?: boolean;
}

// 组件事件
interface Emits {
  /** 验证成功 */
  (e: "verify-success", code: string): void;
  /** 验证失败 */
  (e: "verify-error", error: string): void;
  /** 验证码改变 */
  (e: "code-change", code: string): void;
  /** 发送成功 */
  (e: "send-success"): void;
  /** 发送失败 */
  (e: "send-error", error: string): void;
}

const props = withDefaults(defineProps<Props>(), {
  autoVerify: true,
  disabled: false
});

const emit = defineEmits<Emits>();

// 响应式数据
const verificationCode = ref("");
const sendCodeLoading = ref(false);
const verificationStatus = ref<"success" | "error" | "verifying" | null>(null);
const verificationError = ref("");
const countdown = ref(0);
const countdownTimer = ref<NodeJS.Timeout>();
const remainingSendCount = ref(5);

// 计算属性
const canSendCode = computed(() => {
  return (
    !props.disabled &&
    UserAuthUtils.validateEmail(props.email) &&
    countdown.value === 0 &&
    remainingSendCount.value > 0
  );
});

const sendCodeText = computed(() => {
  if (countdown.value > 0) {
    return `${countdown.value}秒后重发`;
  }
  return "发送验证码";
});

// 监听验证码输入
const onCodeInput = (value: string) => {
  emit("code-change", value);

  // 重置验证状态
  if (verificationStatus.value === "error") {
    verificationStatus.value = null;
    verificationError.value = "";
  }

  // 自动验证
  if (props.autoVerify && UserAuthUtils.validateVerificationCode(value)) {
    verifyCode(value);
  }
};

// 发送验证码
const sendVerificationCode = async () => {
  if (!canSendCode.value) return;

  try {
    sendCodeLoading.value = true;

    const request: SendVerificationCodeRequest = {
      email: props.email,
      verificationType: props.verificationType
    };

    const response = await sendVerificationCodeApi(request);

    if (response.code === 200 && response.data) {
      ElMessage.success("验证码已发送到您的邮箱，请查收");

      // 更新剩余发送次数
      if (response.data.remainingSendCount !== undefined) {
        remainingSendCount.value = response.data.remainingSendCount;
      }

      // 开始倒计时
      startCountdown(response.data.nextSendSeconds || 60);

      emit("send-success");
    } else {
      const errorMsg = response.message || "发送验证码失败";
      ElMessage.error(errorMsg);
      emit("send-error", errorMsg);
    }
  } catch (error) {
    const errorMsg = UserAuthUtils.formatErrorMessage(error);
    ElMessage.error(errorMsg);
    emit("send-error", errorMsg);
  } finally {
    sendCodeLoading.value = false;
  }
};

// 验证验证码
const verifyCode = async (code: string) => {
  if (!UserAuthUtils.validateVerificationCode(code)) {
    return;
  }

  try {
    verificationStatus.value = "verifying";

    const request: VerifyEmailCodeRequest = {
      email: props.email,
      verificationCode: code,
      verificationType: props.verificationType
    };

    const response = await verifyEmailCodeApi(request);

    if (response.code === 200) {
      verificationStatus.value = "success";
      emit("verify-success", code);
    } else {
      verificationStatus.value = "error";
      verificationError.value = response.message || "验证码错误";
      emit("verify-error", verificationError.value);
    }
  } catch (error) {
    verificationStatus.value = "error";
    verificationError.value = UserAuthUtils.formatErrorMessage(error);
    emit("verify-error", verificationError.value);
  }
};

// 开始倒计时
const startCountdown = (seconds: number = 60) => {
  countdown.value = seconds;
  countdownTimer.value = setInterval(() => {
    countdown.value--;
    if (countdown.value <= 0) {
      clearInterval(countdownTimer.value);
    }
  }, 1000);
};

// 手动验证（供外部调用）
const manualVerify = () => {
  if (UserAuthUtils.validateVerificationCode(verificationCode.value)) {
    verifyCode(verificationCode.value);
  } else {
    ElMessage.error("请输入6位数字验证码");
  }
};

// 重置状态
const reset = () => {
  verificationCode.value = "";
  verificationStatus.value = null;
  verificationError.value = "";
  if (countdownTimer.value) {
    clearInterval(countdownTimer.value);
    countdown.value = 0;
  }
};

// 监听邮箱变化，重置状态
watch(
  () => props.email,
  () => {
    reset();
  }
);

// 组件卸载时清理定时器
onUnmounted(() => {
  if (countdownTimer.value) {
    clearInterval(countdownTimer.value);
  }
});

// 暴露方法给父组件
defineExpose({
  manualVerify,
  reset,
  sendVerificationCode,
  verificationCode: computed(() => verificationCode.value),
  isVerified: computed(() => verificationStatus.value === "success")
});
</script>

<style scoped lang="scss">
@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

// 响应式设计
@media (width <= 640px) {
  .email-verification {
    .verification-input {
      flex-direction: column;

      .send-code-btn {
        width: 100%;
      }
    }
  }
}

// 暗色主题适配
@media (prefers-color-scheme: dark) {
  .email-verification {
    .verification-status {
      .status-success {
        background: #064e3b;
        border-color: #065f46;
      }

      .status-error {
        background: #7f1d1d;
        border-color: #991b1b;
      }

      .status-verifying {
        background: #1e293b;
        border-color: #334155;
      }
    }

    .help-info .help-text {
      color: #d1d5db;
    }
  }
}

.email-verification {
  .verification-input {
    display: flex;
    gap: 12px;
    margin-bottom: 16px;

    .el-input {
      flex: 1;
    }

    .send-code-btn {
      flex-shrink: 0;
      border-radius: 8px;
    }
  }

  .verification-status {
    margin-bottom: 16px;

    .status-success,
    .status-error,
    .status-verifying {
      display: flex;
      gap: 8px;
      align-items: center;
      padding: 8px 12px;
      font-size: 14px;
      border-radius: 6px;
    }

    .status-success {
      color: #10b981;
      background: #f0f9ff;
      border: 1px solid #bae6fd;
    }

    .status-error {
      color: #ef4444;
      background: #fef2f2;
      border: 1px solid #fecaca;
    }

    .status-verifying {
      color: #6b7280;
      background: #f8fafc;
      border: 1px solid #e2e8f0;

      .loading {
        animation: spin 1s linear infinite;
      }
    }
  }

  .help-info {
    .help-text {
      display: flex;
      gap: 8px;
      align-items: center;
      margin: 4px 0;
      font-size: 12px;
      color: #6b7280;

      .el-icon {
        font-size: 14px;
      }
    }
  }
}
</style>
